در اين بخش قرار بود كه در رابطه با فريمورك های مختلف ارائه شده جهت بكارگيری فناوری Ajax آشنا شويم . ولی به دليل درخواست تعداد زيادی از خوانندگان مبنی بر آشنائی بيشتر با معماری Ajax ، برنامه نويسی غيرهمزمان در برنامه های وب و شی XMLHttpRequest ، اين بخش را به بررسی موارد فوق اختصاص داديم تا علاقه مندان بتوانند قبل از پرداختن به اصل موضوع با برخی مفاهيم كليدی و مهم بيشتر آشنا شوند .
مقدمه
Ajax يك رويكرد و يا الگوی جديد برای پياده سازی برنامه های وب است كه در آن از اسكريپت های سمت سرويس گيرنده برای مبادله داده با سرويس دهنده وب استفاده می گردد. رويكرد فوق باعث می شود كه صفحات وب بدون نياز به refresh كامل بتوانند بطور پويا بهنگام گردند ( رويائی برای پياده كنندگان برنامه های وب ) . مهمترين دستاورد رويكرد فوق ، ارتباط بدون وقفه و پيوسته كاربران با برنامه های وب است .
برخی از كارشناسان بر اين اعتقاد هستند كه رويكرد فوق بيش از آن كه يك الگو باشد يك فناوری است . در واقع ، Ajax تركيبی از مجموعه فناوری های مرتبط به هم است كه از آنها با يك نگرش جديد در جهت توليد نسل جديدی از برنامه های وب استفاده می گردد .
نام بردن از فناورهائی كه در Ajax از آنها استفاده می گردد كار مشكلی نيست ولی مهم اين است كه بدانيم اين فناورها در كنار يكديگر به چه صورت كار می كنند و هر يك از آنها در Ajax دارای چه مختصاتی است .شكل 1 ، نحوه تعامل و ارتباط اين فناوری ها را از منظر مرورگر نشان می دهد .
شكل 1 : عناصر Ajax
جاوا اسكريپت در Ajax دارای يك نقش محوری و تعيين كننده است و می توان آن را به منزله يك نيروی چسبنده در نظر گرفت كه ساير فناوری ها را با هم مرتبط می نمايد . زمانی كه يك برنامه به داده نياز داشته باشد ، از شی XMLHttpRequest به منظور ايجاد درخواست به سرويس دهنده استفاده می گردد . پس از برگرداندن داده توسط سرويس دهنده ، از فناورهای DOM ( برگرفته شده از Document Object Model ) و CSS ( برگرفته شده از cascading style sheets ) برای بهنگام سازی رابط كاربر مرورگر به صورت پويا استفاده می گردد .
برنامه نويسی وب غيرهمزمان
حرف A موجود در Ajax از Asynchronous گرفته شده است كه در زبان فارسی به غيرهمزمان و يا ناهمگام ترجمه می شود و بيانگر يكی از قابليت های مهم و كليدی الگوی برنامه نويسی Ajax است .
در برنامه های وب سنتی ، تعامل كاربر با برنامه بطور پيوسته نبوده و در مقاطع زمانی خاصی لازم است كاربر در انتظار اتمام يك عمليات باشد . زمانی كه كاربر عمليات خاصی نظير كليك بر روی دكمه موجود بر روی يك فرم را انجام می دهد ، يك درخواست مبتنی بر پروتكل HTTP برای سرويس دهنده وب ارسال می گردد . در ادامه ، سرويس دهنده درخواست را پردازش ( به عنوان نمونه ، انجام برخی محاسبات و يا عمليات مرتبط با بانك های اطلاعاتی ) و نتايج توليد شده را در قالب يك صفحه وب با محتويات جديد برای سرويس گيرنده ارسال می نمايد .
نحوه عملكرد صفحات وب متاثر از ماهيت stateless بودن پروتكل HTTP است . با توجه به اين كه تمامی منطق برنامه معمولا" بر روی سرويس دهنده قرار می گيرد ، نقش مرورگرها صرفا" نمايش بخش رابط كاربر و يا اصطلاحا" اينترفيس برنامه است . سرويس دهنده ، چرخه حيات يك صفحه وب را بطور كامل طی می نمايد و برای مرورگر تگ های HTML ، كدهای CSS و ساير منابع مورد نياز را جهت بازخوانی و نمايش مجدد صفحه ارسال می نمايد . ماهيت فرآيند فوق بگونه ای است كه در دراز مدت نمی تواند رضايت خاطر كامل كاربران را حداقل در سطح بخش رابط كاربر برنامه تامين نمايد . در اين مدل كاربران از يك الگوی stop-start-stop تبعيت می نمايند . كاربران در برخی موارد و با توجه به شرايط حاكم بر برنامه بطور موقت و از روی ناچار ارتباط خود را با برنامه از دست داده و می بايست در انتظار بهنگام سازی صفحه وب درخواستی بمانند .
شكل 2 ، نحوه عملكرد برنامه های وب در يك فرآيند همزمان را نشان می دهد .
شكل 2 : نحوه عملكرد برنامه های وب در يك فرآيند همزمان
( عدم تعامل كاربر با برنامه در زمان درخواست های HTTP )
در ASP.NET زمانی كه يك صفحه داده را برای خود و يا حتی صفحه ای ديگر ارسال می نمايد ، يك postback اتفاق می افتد . در حين اين فرآيند ، وضعيت جاری صفحه به همراه كنترل های موجود بر روی آن جهت پردازش برای سرويس دهنده ارسال می گردند . مكانيزم postback با هدف تامين خواسته هائی نظير نگهداشت وضعيت صفحه و كنترل های سرويس دهنده موجود بر روی آن دنبال می شود . فرآيند فوق گرچه در نهايت می تواند منجر به refresh صفحه وب و نمايش محتويات جديد برای كاربر گردد ولی هزينه انجام آن زياد خواهد بود چراكه اولا" يك حجم داده می بايست برای سرويس دهنده ارسال گردد و ثانيا" ارتباط منطقی كاربر با برنامه از بين خواهد رفت .
يك برنامه وب مبتنی بر Ajax با مدل و يا رويكردی متفاوت نسبت به آنچه اشاره گرديد ، كار می كند . در اين مدل ، تعامل مستمر كاربر با برنامه از طريق معرفی يك نماينده كه بين سرويس گيرنده و سرويس دهنده قرار می گيرد ، تامين می گردد . اين نماينده و يا agent ، با سرويس دهنده بطور غيرهمزمان ارتباط برقرار می نمايد ( از طرف سرويس گيرنده ) تا درخواست HTTP را ايجاد و آن را برای سرويس دهنده ارسال نمايد . وظايف نماينده فوق به اين نقطه ختم نمی گردد و مسئوليت بهنگام سازی صفحه پس از دريافت داده از سرويس دهنده نيز بر عهده وی می باشد .
در مدل غير همزمان ، Ajax engine توسط جاوا اسكريپت فراخوانده می شود تا داده مورد نظر را درخواست نمايد . پس ايجاد درخواست توسط Ajax engine و ارسال آن برای سرويس دهنده و انجام پردازش های ضروری در سمت سرويس دهنده ، نتايج توسط Ajax engine دريافت و بخش رابط كاربر برنامه متناسب با آن بهنگام می گردد .
شكل 3 ، نحوه عملكرد برنامه های وب در يك فرآيند غيرهمزمان را نشان می دهد .
شكل 3 : نحوه عملكرد برنامه های وب در يك فرآيند غيرهمزمان
(ارسال درخواست های HTTP از طريق Ajax engine برای سرويس دهنده)
در هسته Ajax engine ، شی مهم و كليدی XMLHttpRequest قرار دارد كه در ادامه با آن بيشتر آشنا می شويم .
شی XMLHttpRequest
شی XMLHttpRequest به منزله قلب برنامه نويسی Ajax مطرح می گردد چراكه شی فوق باعث می شود جاوا اسكريپت بتواند درخواست هائی را ايجاد تا برای سرويس دهنده ارسال و نتايج ارسالی از سرويس دهنده را نيز پردازش نمايد .
شی فوق اولين مرتبه و به صورت يك شی اكتيوايكس در Internet Explorer 5 عرضه گرديد و هم اينك از آن در اكثر مرورگرها حمايت می گردد . ساير مرورگرها نظير Safari ، Opera ، Mozilla و فايرفاكس پتانسيل های XMLHttpRequest را به صورت يك شی ذاتی جاوا اسكريپت ارائه كرده اند ( در IE 7.0 شی فوق بطور ذاتی در جاوا اسكريپت تعبيه شده است ) .
با توجه به اين كه تاكنون نسخه های مختلفی از شی فوق در مرورگرها پياده سازی شده است ، پياده كنندگان می بايست كد لازم به منظور تشخيص نوع شی فوق را در زمان ايجاد يك نمونه از آن را در برنامه خود پيش بينی نمايند . برای تعيين نسخه در دسترس شی XMLHttpRequest می توان از روشی موسوم به " تشخيص شی " استفاده كرد .
ايجاد يك نمونه از شی XMLHttpRequest با توجه به نوع مرورگر
|
var xmlHttp = null;
if (window.XMLHttpRequest) { //IE7 , Mozilla ,...
xmlHttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); //IE 5.x, 6
}
catch(e) {}
} |
مثال
برای آشنائی با نحوه عملكرد شی فوق و برنامه نويسی وب غيرهمزمان ، در ادامه به بررسی يك نمونه مثال ساده خواهيم پرداخت . فرض كنيد قصد داريم يك درخواست غيرهمزمان به يك منبع موجود بر روی سرويس دهنده (در اين مثال خاص يك صفحه html كه حاوی يك متن ساده است ، صفحه ArticleSummery.htm ) را ايجاد نمائيم . صفحه فوق يك صفحه وب با حداقل اطلاعات و شامل يك متن ايستا است .
صفحه ArticleSummery.htm
|
<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl">
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type" />
<title>تست برنامه نويسی وب غيرهمزمان title>
head>
<body style="font-family: Tahoma;">
<div>در اين مقاله با برنامه نويسی وب همزمان و غيرهمزمان آشنا شديم div>
body>
html> |
مسئوليت ارسال يك درخواست غيرهمزمان به تابع SendRequest سپرده شده است .
ارسال يك درخواست غيرهمزمان
|
كد
|
مرحله
|
function sendRequest(url) {
if (xmlHttp) {
xmlHttp.open("GET", url, true); // true = async |
1
|
فعال كردن ارتباط غيرهمزمان
|
|
xmlHttp.onreadystatechange = onCallback;
|
2
|
نسبت دهی تابع callback
|
|
xmlHttp.setRequestHeader('Content-type','application/x-www-form-urlencoded'); |
|
xmlHttp.send(null);
}
} |
3
|
ارسال درخواست غيرهمزمان
|
توضيحات
-
متد sendRequest ، يك پارامتر كه در واقع URL مربوطه به درخواست HTTP است را دريافت می نمايد .
-
مرحله اول : يك ارتباط غيرهمزمان ايجاد می گردد ( در نظر گرفتن مقدار true به عنوان سومين پارامتر در زمان فعال كردن ارتباط نشان دهنده يك ارتباط غيرهمزمان است ).
-
مرحله دوم : پس از مقداردهی اوليه ارتباط مورد نظر ، به خصلت onreadystatechange شی XMLHttpRequest يك تابع محلی با نام onCallback نسبت داده می شود . توجه داشته باشيد كه فراخوانی تابع فوق به صورت غيرهمزمان است . تابع Callback مشخص می نمايد كه چه زمانی درخواست تكميل و يا بهنگام شده است .
-
مرحله سوم : پس از مشخص كردن نوع محتوا در هدر درخواست ، با استفاده از متد Send شی XMLHttpRequest ، درخواست HTTP برای سرويس دهنده ارسال می گردد .
فراخوانی تابع onCallback
هر مرتبه ای كه وضعيت ready تغيير می يابد ، از تابع callback جهت ايجاد يك درخواست غيرهمزمان استفاده می گردد . در مرحله نهائی ، وضعيت بررسی و بخش رابط كاربر به همراه محتويات برگردانده شده از صفحه ArticleSummery.htm ، بهنگام می گردد.
فراخوانی تابع oncallback
|
كد
|
مرحله
|
function onCallback() {
if (xmlHttp.readyState == 4) { |
1
|
بررسی تكميل عمليات
|
|
if (xmlHttp.status == 200){ |
2
|
مقدار 200 نشان دهنده انجام موفقيت آميز عمليات است
|
|
var r = document.getElementById('results');
r.innerHTML = xmlHttp.responseText;
}
|
3
|
نمايش نتايج
|
else {
alert('Error: ' + xmlHttp.status);
} |
توضيحات
-
وضعيت درخواست از طريق خصلت readyState برگردانده می شود .
-
مرحله اول : در صورتی كه مقدار خصلت readyState شی XMLHttpRequest برابر با مقدار 4 باشد ، درخواست به اتمام رسيده است .
-
مرحله دوم : در ادامه ، پاسخ برگردانده شده از سرويس دهنده بررسی می شود تا اين اطمينان حاصل گردد كه همه چيز با موفقيت انجام شده است .مقدار كد وضعيت 200 مربوط به پروتكل HTTP ، نشان دهنده اين موضوع است كه درخواست با موفقيت انجام شده است .
-
مرحله سوم : در نهايت ، خصلت innerHTML مربوط به عنصر span متاثر از محتويات برگردانده شده ، بهنگام می گردد .
كد زير ، محتويات صفحه Ajax1.aspx را بطور كامل نشان می دهد .
صفحه Ajax1.aspx
|
<%@ Page Language="VB" Culture="fa-IR" %>
<script runat="server">
script>
<html xmlns="http://www.w3.org/1999/xhtml" dir="rtl" >
<head id="Head1" runat="server">
<title>نحوه استفاده از شی XMLHttpRequesttitle>
head>
<body style="font-family: Tahoma">
<form id="form1" runat="server">
<div>
<span id="results">بارگذاری صفحه ...span>
div>
form>
<script type="text/javascript">
var xmlHttp = null;
window.onload = function() {
loadXmlHttp();
sendRequest("ArticleSummery.htm");
}
function loadXmlHttp() {
if (window.XMLHttpRequest) { // IE7, Mozilla, Safari, Opera, etc.
xmlHttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); // IE 5.x and 6
}
catch (e){}
}
}
function sendRequest(url) {
if (xmlHttp) {
xmlHttp.open("GET", url, true); // true = async
xmlHttp.onreadystatechange = onCallback;
xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
// Send request without any additional parameters
xmlHttp.send(null);
}
}
function onCallback() {
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200){
var r = document.getElementById('results');
r.innerHTML = xmlHttp.responseText;
}
else { // HTTP error
alert('Error: ' + xmlHttp.status);
}
}
}
script>
body>
html> |
شكل 4 خروجی مثال فوق را نشان می دهد .
شكل 4 : ايجاد يك درخواست Http غيرهمزمان توسط شی XMLHttpRequest
در اين مثال با نحوه ايجاد يك درخواست HTTP غيرهمزمان توسط شی XMLHttpRequest به صفحه ديگر موجود بر روی سرويس دهنده آشنا شديم . پس از اتمام درخواست ، كاربران صفحه نهائی را كه محتويات عناصر رابط كاربر موجود در آن (يك span ) به صورت پويا بهنگام شده اند ، مشاهده خواهند كرد .
خلاصه
در اين مقاله با برنامه نويسی وب همزمان و غيرهمزمان و نحوه عملكرد شی XMLHttpRequest آشنا شديم . هدف از بيان موارد فوق ، صرفا" آشنائی با الگوی برنامه نويسی وب مبتنی بر Ajax بود . تمامی داستان به اين نقطه ختم نمی شود و در مقالات آتی به ساير پتانسيل های Ajax به منظور پياده سازی برنامه های وب اشاره خواهيم كرد .